﻿/************************************************************************

 This file is part of EscapeFromPrisonPlanet.

 EscapeFromPrisonPlanet is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 EscapeFromPrisonPlanet is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with Foobar.  If not, see <http://www.gnu.org/licenses/>.

************************************************************************/

// All code (c)2012 Scott Bevin. all rights reserved

using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;

namespace LudumDare25Project.Objects
{
    internal class ExplosionSys
    {
        private class Explosion
        {
            public enum States
            {
                Growing,
                Shrinking,
            }

            public States State = States.Growing;

            public Vector2 Position;

            public Texture2D[] Textures = new Texture2D[3];
            public float[] Scales = new float[3];
            public float[] Rots = new float[3];
        }

        private List<Texture2D> redTextures = new List<Texture2D>();
        private List<Texture2D> orangeTextures = new List<Texture2D>();
        private List<Texture2D> yellowTextures = new List<Texture2D>();

        private List<Explosion> explosions = new List<Explosion>();

        private Random rnd = new Random();

        public ExplosionSys(ContentManager content)
        {
            LoadRed(content);
            LoadOrange(content);
            LoadYellow(content);
        }

        private void LoadRed(ContentManager content)
        {
            bool done = false;
            int counter = 0;

            while (!done)
            {
                try
                {
                    Texture2D tex = content.Load<Texture2D>("Img/Explosion/ExplosionRed" + counter.ToString());
                    redTextures.Add(tex);
                    counter++;
                }
                catch (Exception e)
                {
                    done = true;
                }
            }
        }

        private void LoadOrange(ContentManager content)
        {
            bool done = false;
            int counter = 0;

            while (!done)
            {
                try
                {
                    Texture2D tex = content.Load<Texture2D>("Img/Explosion/ExplosionOrange" + counter.ToString());
                    orangeTextures.Add(tex);
                    counter++;
                }
                catch (Exception e)
                {
                    done = true;
                }
            }
        }

        private void LoadYellow(ContentManager content)
        {
            bool done = false;
            int counter = 0;

            while (!done)
            {
                try
                {
                    Texture2D tex = content.Load<Texture2D>("Img/Explosion/ExplosionYellow" + counter.ToString());
                    yellowTextures.Add(tex);
                    counter++;
                }
                catch (Exception e)
                {
                    done = true;
                }
            }
        }

        public void AddExplosion(Vector2 pos)
        {
            Explosion exp = new Explosion();
            exp.Position = pos;
            exp.State = Explosion.States.Growing;

            exp.Scales[0] = -0.5f;
            exp.Scales[1] = -0.25f;
            exp.Scales[2] = 0.0f;

            exp.Textures[0] = redTextures[rnd.Next(redTextures.Count)];
            exp.Textures[1] = orangeTextures[rnd.Next(redTextures.Count)];
            exp.Textures[2] = yellowTextures[rnd.Next(redTextures.Count)];

            exp.Rots[0] = RandomFloat(0, MathHelper.TwoPi);
            exp.Rots[1] = RandomFloat(0, MathHelper.TwoPi);
            exp.Rots[2] = RandomFloat(0, MathHelper.TwoPi);

            explosions.Add(exp);
        }

        public void Update(float dt)
        {
            for (int i = 0; i < explosions.Count; )
            {
                for (int j = 0; j < 3; ++j)
                {
                    if (explosions[i].State == Explosion.States.Growing)
                    {
                        explosions[i].Scales[j] += dt * 10.0f;
                        explosions[i].Scales[j] = Math.Min(explosions[i].Scales[j], 1.0f);
                    }
                    else if (explosions[i].State == Explosion.States.Shrinking)
                    {
                        explosions[i].Scales[j] -= dt * 10.0f;
                        explosions[i].Scales[j] = Math.Max(explosions[i].Scales[j], 0.0f);
                    }
                }

                if (explosions[i].State == Explosion.States.Growing)
                {
                    if (explosions[i].Scales[0] >= 0.99f)
                        explosions[i].State = Explosion.States.Shrinking;

                    ++i;
                }
                else
                {
                    if (explosions[i].Scales[0] <= 0.0f)
                        explosions.RemoveAt(i);
                    else
                        ++i;
                }
            }
        }

        public void Render(SpriteBatch sprites)
        {
            foreach (Explosion exp in explosions)
            {
                for (int i = 0; i < 3; ++i)
                {
                    if (exp.Scales[i] > 0.0f)
                    {
                        sprites.Draw(
                            exp.Textures[i],
                            exp.Position,
                            null,
                            Color.White,
                            exp.Rots[i],
                            new Vector2(exp.Textures[i].Width, exp.Textures[i].Height) * 0.5f,
                            exp.Scales[i] * 3.0f,
                            SpriteEffects.None,
                            0.0f);
                    }
                }
            }
        }

        public float RandomFloat(float min, float max)
        {
            return min + (max - min) * (float)rnd.NextDouble();
        }
    }
}